package com.unit3;

// Happy Days！
// Author:bamboo
public class SingleLinkedList {
    //初始化头节点，头节点不动，不存储具体数据
    private StudentNode head = new StudentNode(0,"");
    //遍历链表
    public void list(){
        StudentNode temp = head.next;
        if (temp == null) {
            System.out.println("链表为空");
            return;
        }
        //当节点的地址域不为空时，一直遍历打印节点数据，temp为空时跳出循环
        while (temp != null) {
            System.out.println(temp);
            //指针后移，继续遍历
            temp =temp.next;
        }
    }
    //添加节点
    //从尾部添加节点到单链表 不考虑编号顺序
    public void add(StudentNode studentNode){
        // 因为head不能动，所以需要一个temp辅助变量作为指针
        StudentNode temp= head;
        // 遍历链表，找到最后
        while (true){
            // 找到链表最后
            if (temp.next == null){
                break;
            }
            // 没有找到链表最后，temp指针后移
            temp = temp.next;

        }
        //当退出while循环时，temp指向链表的最后
        //让最后的这个节点的next指向新的节点
        temp.next=studentNode;
    }
    //顺序添加
    public void addByOrder(StudentNode studentNode){
        //因为head不能动，所以需要一个temp辅助变量作为指针
        //我们找的temp时位于添加位置的前一个节点，否则插入不了
        StudentNode temp = head;
        //表示添加的节点的编号是否已经存在，默认false表示不存在
        boolean flag = false;
        while(true) {
            if (temp.next == null) {
                break;
            }
            //如果添加的节点的编号小于temp的下一个节点的编号，那说明添加的节点编号大小在temp和temp.next两个节点编号之间
            //找到了要添加的位置，跳出循环
            if (temp.next.no > studentNode.no) {
                break;
            }
            // 表示单链表中已存在
            if (temp.next.no == studentNode.no) {
                flag = true;
                break;
            }
            temp = temp.next;
        }
        // 判断flag
        if (flag) {
            //flag =true
            System.out.println("已经存在该学生信息，不能重复添加");
        }else {
            //flag=false
            studentNode.next = temp.next;
            temp.next = studentNode;
        }
    }
    //修改
    public void update(StudentNode studentNode){
        if (head.next == null) {
            System.out.println("链表为空");
            return;
        }
        StudentNode temp = head.next;
        // 标识节点是否找到
        boolean flag = false;
        while (true){
            if (temp == null) {
                //遍历完单链表，跳出循环
                break;
            }
            if (temp.no == studentNode.no) {
                //找到要修改的节点
                flag = true;
                break;
            }
            //temp 后移
            temp = temp.next;

        }
        if (flag) {
            temp.name = studentNode.name;

        }else {
            System.out.println("没有找到编号为"+temp.no+"的节点，不能修改");
        }
    }
    //删除：根据编号删除学生信息
    public void delete(int no) {
        StudentNode temp = head;
        boolean flag = false;
        if (head.next == null) {
            System.out.println("链表为空");
            return;
        }

        while (true) {
            if (temp.next == null) {
                break;
            }
            if (temp.next.no == no) {
                flag = true;
                break;
            }
            temp = temp.next;
        }
        if (flag) {
            //删除
            temp.next = temp.next.next;

        }else {
            System.out.println("要删除的节点找不到");
        }
    }
    //获取有效节点
    public static int getLength(StudentNode head) {
        //如果是空列表
        if (head.next == null) {
            return 0;
        }
        int length = 0;
        StudentNode curr = head.next;
        while (curr != null) {
            length++;
            curr = curr.next;
        }
        return length;
    }
    //节点查询
    public static StudentNode findLastByIndex(StudentNode head,int index) {
        //链表为空
        if (head.next == null) {
            //没有找到返回null
            return null;
        }
        //获取有效点的个数
        int size = getLength(head);
        //判断index是否符合要求
        if (index <=0 || index > size) {
            throw new RuntimeException("找不到该节点");
        }
        //定义辅助变量，利用for循环定位到倒数index个节点
        StudentNode curr = head.next;
        for (int i = 0; i < size - index;i++) {
            curr = curr.next;
        }
        return curr;
    }
    public StudentNode getHead() {
        return head;
    }
}
